import { UserGroupEntity } from './../../entities/userGroup.entity';
import { UserEntity } from './../../entities/user.entity';
import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { GroupEntity } from '../../entities/group.entity';
import { GroupMessageEntity } from '../../entities/groupMessage.entity';
import { FriendEntity } from '../../entities/friend.entity';
import { FriendMessageEntity } from '../../entities/friendMessage.entity';
import { json } from 'express';

// @WebSocketGateway({namespace: 'ws'})
@WebSocketGateway()
export class ChatGateway {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    @InjectRepository(UserGroupEntity)
    private readonly userGroupRepository: Repository<UserGroupEntity>,
    @InjectRepository(GroupEntity)
    private readonly groupRepository: Repository<GroupEntity>,
    @InjectRepository(GroupMessageEntity)
    private readonly groupMessageRepository: Repository<GroupMessageEntity>,
    @InjectRepository(FriendEntity)
    private readonly friendRepository: Repository<FriendEntity>,
    @InjectRepository(FriendMessageEntity)
    private readonly friendMessageRepository: Repository<FriendMessageEntity>,
  ) {}

  // 服务
  @WebSocketServer()
  server: Server

  // socket连接钩子
  async handleConnection(client: Socket) {
    console.log('socket连接成功');
    // let userRoom = client.handshake.query.user_id;
    // const defaultGroup = await this.groupRepository.find({name: 'public'});
    // if(!defaultGroup.length) {
    //   this.groupRepository.save({
    //     groupId: 'public',
    //     groupName: 'public',
    //     userId: 'admin',
    //     createTime: new Date().valueOf()
    //   })
    // }
    // // 连接默认加入public房间
    // client.join('public')
    // if (userRoom) {
    //   client.join(userRoom);
    // }
    return 'socket连接成功';
  }

  async handleDisconnect() {
    console.log('socket断开连接');
    return 'socket断开连接';
  }
  // 练习
  @SubscribeMessage('events')
  async onEvents(client, message) {
    console.log('接收消息' +  JSON.stringify(message));
    client.emit('events', message)
    // 发送给所有客户端，除了发送者
    client.broadcast.emit('events', message);
  }

  // 创建群
  @SubscribeMessage('addGroup')
  async addGroup(@ConnectedSocket() client: Socket, @MessageBody() data: GroupEntity) {
    try {
      const isHaveGroup = await this.groupRepository.findOne({name: data.name});
      if (isHaveGroup) {
        return this.server.to(data.id).emit('addGroup', {code:1, message: '该群名字已存在', data: isHaveGroup});
      }
      data = await this.groupRepository.save(data);
      client.join(data.id);
      const group = await this.userGroupRepository.save({
        group_id: data.id,
        user_id: data.owner
      });
      this.server.to(group.group_id).emit('addGroup', {code: 0, message: `成功创建群${data.name}`, data:group});
    } catch(e) {
      this.server.to(data.id).emit('addGroup', {code: 2, message:'创建群失败', data:e});
    }
  }

  // 加入群组
  @SubscribeMessage('joinGroup')
  async joinGroup(@ConnectedSocket() client: Socket, @MessageBody() data: UserGroupEntity) {
    try {
      const group = await this.groupRepository.findOne({id: data.group_id});
      let userGroup = await this.userGroupRepository.findOne({group_id: group.id, user_id: data.user_id});
      const user = await this.userRepository.findOne({id: data.user_id});
      if (group) {
        if (!userGroup) {
          data.group_id = group.id
          userGroup = await this.userGroupRepository.save(data);
        }
        client.join(group.id)
        let res = {
          group: group,
          user: user,
        }
        this.server.to(group.id).emit('joinGroup', {code: 0, message:`${user.username}加入群${group.name}`, data: res});
      } else {
        this.server.to(data.user_id).emit('joinGroup', {code:1, message:'该群不存在', data:''});
      }
    } catch(e) {
      this.server.to(data.user_id).emit('joinGroup', {code:2, message:'进群失败', data:e});
    }
  }

  // 加入群的socket连接
  @SubscribeMessage('joinGroupSocket')
  async joinGroupSocket(@ConnectedSocket() client: Socket, @MessageBody() data: UserGroupEntity) {
    try {
      const group = await this.groupRepository.findOne({id: data.group_id});
      const user = await this.userRepository.findOne({id: data.user_id});
      if(group) {
        client.join(group.id)
        let res = { group: group, user: user}
        this.server.to(group.id).emit('joinGroupSocket', {code: 0, message:`${user.username}加入群${group.name}`, data: res});
      } else {
        this.server.to(data.user_id).emit('joinGroupSocket', {code:1, message:'该群不存在', data:''});
      }
    } catch(e) {
      this.server.to(data.user_id).emit('joinGroupSocket', {code:2, message:'进群失败', data:e});
    }
  }

  // 发送群消息
  @SubscribeMessage('groupMessage')
  async sendGroupMessage(@MessageBody() data: GroupMessageEntity) {
    try {

    } catch(e) {

    }
  }

  // 添加好友
  @SubscribeMessage('addFriend')
  async addFriend(@ConnectedSocket() client: Socket, @MessageBody() data: FriendEntity) {
    try {
      if (data.user_id && data.friend_id) {
        if (data.user_id === data.friend_id) {
          return this.server.to(data.user_id).emit('addFriend', {code:1, message:'不能添加自己为好友', data:''});
        }
        const isHave1 = await this.friendRepository.find({user_id: data.user_id, friend_id: data.friend_id});
        const isHave2 = await this.friendRepository.find({user_id: data.friend_id, friend_id: data.user_id});
        const roomId = data.user_id > data.friend_id ? data.user_id + data.friend_id : data.friend_id + data.user_id;
        if (isHave1.length || isHave2.length) {
          this.server.emit('addFriend', {code:0, message:'已经有该好友', data:data});
          return;
        }
        const friend = await this.userRepository.find({id: data.friend_id});
        const user = await this.userRepository.find({id: data.user_id});
        if (!friend) {
          this.server.to(data.user_id).emit('addFriend', {code:1, message:'该好友不存在', data:''})
          return;
        }
        // 双方都添加好友，并存入数据库
        await this.friendRepository.save(data);
        let update = data;
        // let  friendData = JSON.parse(JSON.stringify(data));
        const friendId = data.friend_id;
        update.friend_id = update.user_id;
        update.user_id = friendId;
        delete update.id;
        await this.friendRepository.save(update);
        client.join(roomId);
        this.server.to(data.user_id).emit('addFriend', {code:0, message:'添加好友成功', data:''});
        this.server.to(data.friend_id).emit('addFriend', {code:0, message:'你正在被一个人添加', data:''});
      }
    } catch(e) {
      return {code:2, message:'添加好友失败', data:e};
    }
  }

  // 进入好友个人聊天
  @SubscribeMessage('joinFriendSocket')
  async joinFriend(@ConnectedSocket() client: Socket, @MessageBody() data: FriendEntity) {
    try {
      if (data.user_id && data.friend_id) {
        const isUserInFriend = await this.friendRepository.find({user_id: data.user_id, friend_id: data.friend_id});
        const roomId = data.user_id > data.friend_id ? data.user_id + data.friend_id : data.friend_id + data.user_id;
        if (isUserInFriend) {
          client.join(roomId);
          this.server.to(data.user_id).emit('joinFriendSocket', {code:0, message:'进入好友私聊成功', data: isUserInFriend});
          this.server.to(data.friend_id).emit('joinFriendSocket', {code:0, message:'进入好友私聊成功', data: isUserInFriend});
          return;
        }
      }
    } catch(e) {
      this.server.to(data.user_id).emit('joinFriendSocket', {code:2, message:'进入好友房间失败', data:e});
    }
  }

  // 发送好友聊天
  @SubscribeMessage('friendMessage')
  async friendMessage(@ConnectedSocket() client: Socket, @MessageBody() data: FriendMessageEntity) {
    try {
      if (data.user_id && data.friend_id) {
        const roomId = data.user_id > data.friend_id ? data.user_id + data.friend_id : data.friend_id + data.user_id;
        client.join(roomId);
        await this.friendMessageRepository.save(data);
        this.server.to(roomId).emit('friendMessage', {code:0, message:'', data});
      }
    } catch(e) {
      this.server.to(data.user_id).emit('friendMessage', {code:2, message:'发送消息失败', data:e});
    }
  }
}
